|
Technote 1153Thread-Safe Toolbox Access From MRJBy Jens Alfke |
CONTENTSHow We Play Safely With the
Toolbox |
J ava is pervasively multi-threaded. The Mac OS isn’t. Most of it isn’t re-entrant, and parts of it are very dependent on global state that needs to remain consistent from one call to the next. This can cause big problems when trying to call the Mac OS directly from Java. This technote describes synchronization techniques that will allow your native or JDirect code to play safely when making OS or Toolbox calls, especially as we move forward to Mac OS X. |
How We Play Safely With the ToolboxAs we all know, the basics of the Mac OS and Toolbox
(which for simplicity I’ll just lump together as the
“Toolbox” here) were designed in the early 1980’s for a
machine that could run only a single app at a time and a
single thread of execution in that app. Things have been
improved a bit since that time, but the constraints of that
basic design require that the Toolbox is still only
single-threaded. Cooperative multitasking between
applications means process switching occurs only at well
known times (when This causes problems when trying to run multiple threads
in a Mac OS app. Toolbox calls are not re-entrant, which
means that while one thread is executing a Toolbox call, no
other thread can enter the Toolbox. Furthermore, the pervasive use of
global state (like the current We had to deal with these issues in implementing the AWT for MRJ 2.1, since most of the AWT is written in Java code that calls the Toolbox via JDirect2. We used a pretty standard solution of using “critical sections” in the code wherever the Toolbox is used, with only one thread able to enter such a critical section at a time. In Java terms, this is implemented by having a single global object (accessed via a public static variable) serve as a synchronization lock, and putting all critical sections into Java blocks synchronized to that object. This object is known as:
(In other words, it’s a static final variable called
We on the MRJ team call this “LOCKing” or “using the LOCK”, capitalized as shown. (When saying it, you emphasize the first syllable to indicate that it’s capitalized...) Why You Should CareWe implemented this so that our own AWT would work correctly. But if other developers are going to write code that uses JDirect -- and many of you are -- and if that code is going to run in apps that also use AWT, then we need to use the same synchronization technique so that your code doesn’t step on our code and vice versa. Thus, this technote. ExampleHere’s a simple example showing a fully synchronized
Native-code (JNI)This isn’t an issue specific to JDirect. If you write
native methods (probably using JNI) that call the Toolbox,
the same issues can arise. If your native code alters
Toolbox state like the current port or the state inside a
|
|
Thanks to the usual suspects.